#!/usr/bin/perl
unshift (@INC, "/home/gslab/Subroutines");
require ("basic_input_no_loss.pl");
require ("basic_input_full_loss.pl");
require ("get_reqd_percentage.pl");
require ("pass_or_fail_remote.pl");
require ("pass_or_fail_for_op_chain.pl");
require ("basic_input_for_opchain.pl");

system("rm summary.txt");                                                                       #removing the previous execution log files.
system("rm logop.txt");
system("rm prog_exit_status_rule.txt");
system("rm prog_exit_status_clear.txt");
open(STDOUT, " | tee -ai logop.txt");
system("sudo iptables -F");                                            #This line is to clear the iptables before execution of all the test cases.
$indexfin = -1;
@aaa = 0;


print("-------------------START OF PROGRAM-------------------\n");

print("--------Executing test case TCR005--------\n");                                        #The only inputs are the test case ID, the rule and the ping command.
print("Description: Testing iptables by blocking UDP traffic on INPUT chain of VM2 and sending UDP packet from VM1\n");
$tcid = TCR005;                                                                               #This is where the user has to specify the test case ID.
$rule = 'sudo iptables -A INPUT -p udp -j DROP';                                              #This the rule to be tested.
$hping = 'sudo hping3 -c 2 -V -2 10.0.2.16';                                                  #This is the ping command for testing the rule.
system("echo Now we will be entering VM2");
system("./expcall1.exp");
system("echo Now we are in the VM1 again");
($setup_s_or_fail,$ping_s_or_fail,$clear_s_or_fail,$testcase_s_or_fail) = &basic_input_full_loss($rule,$hping);  #This is the basic function that is called. 
&tot_exec_success_or_fail1($setup_s_or_fail,$ping_s_or_fail,$clear_s_or_fail,$tcid);          #This function is for printing the specific results.
($report,$indexfin) = &pass_or_fail_remote($testcase_s_or_fail,$tcid,$indexfin,$ping_s_or_fail,$ping_s_or_fail,$setup_s_or_fail,$clear_s_or_fail);
$aaa[$indexfin] = $report;



print("--------Executing test case TCR006--------\n");
print("Description: Testing iptables by blocking ICMP traffic on INPUT chain of VM2 and sending ICMP packet from VM1\n");
$tcid = TCR006;
$rule = 'sudo iptables -A INPUT -p icmp -j DROP';
$hping = 'sudo hping3 -c 2 -V -1 10.0.2.16';
system("echo Now we will be entering VM2");
system("./expcall2.exp");
system("echo Now we are in the VM1 again");
($setup_s_or_fail,$ping_s_or_fail,$clear_s_or_fail,$testcase_s_or_fail) = &basic_input_full_loss($rule,$hping);
&tot_exec_success_or_fail1($setup_s_or_fail,$ping_s_or_fail,$clear_s_or_fail,$tcid);
($report,$indexfin) = &pass_or_fail_remote($testcase_s_or_fail,$tcid,$indexfin,$ping_s_or_fail,$ping_s_or_fail,$setup_s_or_fail,$clear_s_or_fail);
$aaa[$indexfin] = $report;



print("--------Executing test case TCR007--------\n");
print("Description: Test iptables by blocking TCP packets outgoing from VM1 and sending TCP packet to VM2\n");
$tcid = TCR007;
$rule = 'sudo iptables -A OUTPUT -p tcp -j DROP';
$hping = 'sudo hping3 -c 2 -V -S 10.0.2.16';
($setup,$rule,$clear,$tc_success,$cmdntfound,$flagerrcmd) = &basic_input_for_opchain($rule,$hping);
&tc_exec_success_fail_outputchain($setup,$rule,$clear,$tcid);
($report,$indexfin) = &pass_or_fail_for_op_chain($tc_success,$setup,$tcid,$indexfin,$cmdntfound,$flagerrcmd);
$aaa[$indexfin] = $report;



print("--------Executing test case TCR008--------\n");
print("Description: Test iptables by blocking UDP packets outgoing from VM1 and sending UDP packet to VM2\n");
$tcid = TCR008;
$rule = 'sudo iptables -A OUTPUT -p udp -j DROP';
$hping = 'sudo hping3 -c 2 -V -2 10.0.2.16';
($setup,$rule,$clear,$tc_success,$cmdntfound,$flagerrcmd) = &basic_input_for_opchain($rule,$hping);
&tc_exec_success_fail_outputchain($setup,$rule,$clear,$tcid);
($report,$indexfin) = &pass_or_fail_for_op_chain($tc_success,$setup,$tcid,$indexfin,$cmdntfound,$flagerrcmd);
$aaa[$indexfin] = $report;



print("--------Executing test case TCR009--------\n");
print("Description: Test iptables by blocking ICMP packets outgoing from VM1 and sending ICMP packet to VM2\n");
$tcid = TCR009;
$rule = 'sudo iptables -A OUTPUT -p icmp -j DROP';
$hping = 'sudo hping3 -c 2 -V -1 10.0.2.16';
($setup,$rule,$clear,$tc_success,$cmdntfound,$flagerrcmd) = &basic_input_for_opchain($rule,$hping);
&tc_exec_success_fail_outputchain($setup,$rule,$clear,$tcid);
($report,$indexfin) = &pass_or_fail_for_op_chain($tc_success,$setup,$tcid,$indexfin,$cmdntfound,$flagerrcmd);
$aaa[$indexfin] = $report;



print("--------Executing test case TCR010--------\n");
print("Description: Test iptables by blocking outgoing packets to IP Address of VM2 and send packet from VM1 to VM2\n");
$tcid = TCR010;
$rule = 'sudo iptables -A OUTPUT -d 10.0.2.16 -j DROP';
$hping = 'sudo hping3 -c 2 -V -2 10.0.2.16';
($setup,$rule,$clear,$tc_success,$cmdntfound,$flagerrcmd) = &basic_input_for_opchain($rule,$hping);
&tc_exec_success_fail_outputchain($setup,$rule,$clear,$tcid);
($report,$indexfin) = &pass_or_fail_for_op_chain($tc_success,$setup,$tcid,$indexfin,$cmdntfound,$flagerrcmd);
$aaa[$indexfin] = $report;



print("--------Executing test case TCR014--------\n");                 
print("Description: Test iptables by blocking UDP traffic on INPUT chain of VM2 and sending TCP packet from VM1\n");
$tcid = TCR014;                                                        
$rule = 'sudo iptables -A INPUT -p udp -j DROP';                       
$hping = 'sudo hping3 -c 2 -V 10.0.2.16';                               
system("echo Now we will be entering VM2");
system("./expcall1.exp");
system("echo Now we are in the VM1 again");
($setup_s_or_fail,$ping_s_or_fail,$clear_s_or_fail,$testcase_s_or_fail) = &basic_input_no_loss($rule,$hping);     
&tot_exec_success_or_fail1($setup_s_or_fail,$ping_s_or_fail,$clear_s_or_fail,$tcid);                 
($report,$indexfin) = &pass_or_fail_remote($testcase_s_or_fail,$tcid,$indexfin,$ping_s_or_fail,$ping_s_or_fail,$setup_s_or_fail,$clear_s_or_fail);
$aaa[$indexfin] = $report;



print("--------Executing test case TCR015--------\n");
print("Description: Testing iptables by blocking UDP traffic on INPUT chain of VM2 and sending ICMP packet from VM1\n");
$tcid = TCR015;
$rule = 'sudo iptables -A INPUT -p udp -j DROP';
$hping = 'sudo hping3 -c 2 -V -1 10.0.2.16';
system("echo Now we will be entering VM2");
system("./expcall1.exp");
system("echo Now we are in the VM1 again");
($setup_s_or_fail,$ping_s_or_fail,$clear_s_or_fail,$testcase_s_or_fail) = &basic_input_no_loss($rule,$hping);
&tot_exec_success_or_fail1($setup_s_or_fail,$ping_s_or_fail,$clear_s_or_fail,$tcid);
($report,$indexfin) = &pass_or_fail_remote($testcase_s_or_fail,$tcid,$indexfin,$ping_s_or_fail,$ping_s_or_fail,$setup_s_or_fail,$clear_s_or_fail);
$aaa[$indexfin] = $report;



print("--------Executing test case TCR016--------\n");
print("Description: Test iptables by blocking ICMP traffic on INPUT chain of VM2 and sending TCP packet from VM1\n");
$tcid = TCR016;
$rule = 'sudo iptables -A INPUT -p icmp -j DROP';
$hping = 'sudo hping3 -c 2 -V 10.0.2.16';
system("echo Now we will be entering VM2");
system("./expcall2.exp");
system("echo Now we are in the VM1 again");
($setup_s_or_fail,$ping_s_or_fail,$clear_s_or_fail,$testcase_s_or_fail) = &basic_input_no_loss($rule,$hping);
&tot_exec_success_or_fail1($setup_s_or_fail,$ping_s_or_fail,$clear_s_or_fail,$tcid);
($report,$indexfin) = &pass_or_fail_remote($testcase_s_or_fail,$tcid,$indexfin,$ping_s_or_fail,$ping_s_or_fail,$setup_s_or_fail,$clear_s_or_fail);
$aaa[$indexfin] = $report;



print("--------Executing test case TCR017--------\n");
print("Description: Test iptables by blocking ICMP traffic on INPUT chain of VM2 and sending UDP packet from VM1\n");
$tcid = TCR017;
$rule = 'sudo iptables -A INPUT -p icmp -j DROP';
$hping = 'sudo hping3 -c 2 -V -2 10.0.2.16';
system("echo Now we will be entering VM2");
system("./expcall2.exp");
system("echo Now we are in the VM1 again");
($setup_s_or_fail,$ping_s_or_fail,$clear_s_or_fail,$testcase_s_or_fail) = &basic_input_no_loss($rule,$hping);
&tot_exec_success_or_fail1($setup_s_or_fail,$ping_s_or_fail,$clear_s_or_fail,$tcid);
($report,$indexfin) = &pass_or_fail_remote($testcase_s_or_fail,$tcid,$indexfin,$ping_s_or_fail,$ping_s_or_fail,$setup_s_or_fail,$clear_s_or_fail);
$aaa[$indexfin] = $report;



print("--------Executing test case TCR018--------\n");
print("Description: Test iptables by blocking ICMP traffic on OUTPUT chain of VM2 and sending UDP packet from VM1\n");
$tcid = TCR018;
$rule = 'sudo iptables -A OUTPUT -p icmp -j DROP';
$hping = 'sudo hping3 -c 2 -V -2 10.0.2.16';
system("echo Now we will be entering VM2");
system("./expcall3.exp");
system("echo Now we are in the VM1 again");
($setup_s_or_fail,$ping_s_or_fail,$clear_s_or_fail,$testcase_s_or_fail) = &basic_input_full_loss($rule,$hping);
&tot_exec_success_or_fail1($setup_s_or_fail,$ping_s_or_fail,$clear_s_or_fail,$tcid);
($report,$indexfin) = &pass_or_fail_remote($testcase_s_or_fail,$tcid,$indexfin,$ping_s_or_fail,$ping_s_or_fail,$setup_s_or_fail,$clear_s_or_fail);
$aaa[$indexfin] = $report;



print("--------Executing test case TCR019--------\n");
print("Description: Test iptables by blocking outgoing tcp packets from VM1 to a certain port on VM2\n");
$tcid = TCR019;
$rule = 'sudo iptables -A OUTPUT -p tcp --dport 5000 -j DROP';
$hping = 'sudo hping3 -c 2 -V -S -p 5000 10.0.2.16';
($setup,$rule,$clear,$tc_success,$cmdntfound,$flagerrcmd) = &basic_input_for_opchain($rule,$hping);
&tc_exec_success_fail_outputchain($setup,$rule,$clear,$tcid);
($report,$indexfin) = &pass_or_fail_for_op_chain($tc_success,$setup,$tcid,$indexfin,$cmdntfound,$flagerrcmd);
$aaa[$indexfin] = $report;



print("--------Executing test case TCR023--------\n");
print("Description: Test iptables by blocking outgoing packets from a certain port on VM1\n");
$tcid = TCR023;
$rule = 'sudo iptables -A OUTPUT -p tcp --sport 5000 -j DROP';
$hping = 'sudo hping3 -c 2 -V -S -s 5000 10.0.2.16';
($setup,$rule,$clear,$tc_success,$cmdntfound,$flagerrcmd) = &basic_input_for_opchain($rule,$hping);
&tc_exec_success_fail_outputchain($setup,$rule,$clear,$tcid);
($report,$indexfin) = &pass_or_fail_for_op_chain($tc_success,$setup,$tcid,$indexfin,$cmdntfound,$flagerrcmd);
$aaa[$indexfin] = $report;



print("--------Executing test case TCR025--------\n");
print("Description: Test iptables by blocking all outgoing packets from VM1\n");
$tcid = TCR025;
$rule = 'sudo iptables -A OUTPUT -s 10.0.2.15 -j DROP';
$hping = 'sudo hping3 -c 2 -V -S -s 5000 10.0.2.16';
($setup,$rule,$clear,$tc_success,$cmdntfound,$flagerrcmd) = &basic_input_for_opchain($rule,$hping);
&tc_exec_success_fail_outputchain($setup,$rule,$clear,$tcid);
($report,$indexfin) = &pass_or_fail_for_op_chain($tc_success,$setup,$tcid,$indexfin,$cmdntfound,$flagerrcmd);
$aaa[$indexfin] = $report;



print("--------Executing test case TCR028--------\n");
print("Test iptables DROP policy on OUTPUT chain\n");
$tcid = TCR028;
$rule = 'sudo iptables -P OUTPUT DROP';
$hping = 'sudo hping3 -c 2 -V -S 10.0.2.16';
($setup,$rule,$clear,$tc_success,$cmdntfound,$flagerrcmd) = &basic_input_for_opchain($rule,$hping);
&tc_exec_success_fail_outputchain($setup,$rule,$clear,$tcid);
($report,$indexfin) = &pass_or_fail_for_op_chain($tc_success,$setup,$tcid,$indexfin,$cmdntfound,$flagerrcmd);
$aaa[$indexfin] = $report;



print("--------Executing test case TCR046--------\n");
print("Description: Test iptables by blocking outgoing udp packets from VM1 to a certain port on VM2\n");
$tcid = TCR046;
$rule = 'sudo iptables -A OUTPUT -p udp --dport 5000 -j DROP';
$hping = 'sudo hping3 -c 2 -V -2 -p 5000 10.0.2.16';
($setup,$rule,$clear,$tc_success,$cmdntfound,$flagerrcmd) = &basic_input_for_opchain($rule,$hping);
&tc_exec_success_fail_outputchain($setup,$rule,$clear,$tcid);
($report,$indexfin) = &pass_or_fail_for_op_chain($tc_success,$setup,$tcid,$indexfin,$cmdntfound,$flagerrcmd);
$aaa[$indexfin] = $report;



print("--------Executing test case TCR054--------\n");
print("Description: Test iptables by blocking packets destined for a particular port and IP Address of VM2\n");
$tcid = TCR054;
$rule = 'sudo iptables -A OUTPUT -p tcp --dport 5000 -d 10.0.2.16 -j DROP';
$hping = 'sudo hping3 -c 2 -V -S -p 5000 10.0.2.16';
($setup,$rule,$clear,$tc_success,$cmdntfound,$flagerrcmd) = &basic_input_for_opchain($rule,$hping);
&tc_exec_success_fail_outputchain($setup,$rule,$clear,$tcid);
($report,$indexfin) = &pass_or_fail_for_op_chain($tc_success,$setup,$tcid,$indexfin,$cmdntfound,$flagerrcmd);
$aaa[$indexfin] = $report;



#Each test case returns a string which has information as to whether test case is passed or not. This is pushed onto an array and printed at the end of the program.
print("\n-------------Final Report---------------\n");
foreach $rep (@aaa){
	print("$rep\n");
}
#open(OUTFILE, ">summary.txt");
#print OUTFILE ("@aaa\n");


print("\n-------------------END OF PROGRAM---------------------\n");



#This function displays the commands.
sub disp_command{                                                             #Subroutine for displaying the commands.
	my($com1,$com2) = @_;
	print("---------First command was----------\n");
	print("$com1\n");
	print("---------Second command was----------\n");
	print("$com2\n");
}

#This function displays the table.
sub disp_table{                                                                #Subroutine for displaying the table at any time.
	system("sudo iptables -L");
	print("\n");
}



#If setup, rule and cleardown are successful, then overall successful, else, not.
sub tot_exec_success_or_fail1{
	my($setupex,$ruleex,$clearex,$tcex) = @_;
#	if ($ruleex ==1){
	if ($setupex == 1 && $ruleex ==1 && $clearex ==1){
		print("Test case ID $tcex-->Complete test case execution: SUCCESSFUL\n");
	}
	else{
		print("Test case ID $tcex-->Comelete test case execution: ERROR\n");
	}
	if($setupex ne 1){
		print("Rule configuration for test case ID $tcex: FAIL\n");
	}
	if($ruleex ne 1){
		print("Rule execution for test case ID $tcex: FAIL\n");
	}
	if($clearex ne 1){
		print("CLeardown phase for test case ID $tcex: FAIL\n");
	}
}

#Similar checking for rules involving the output chain
sub tc_exec_success_fail_outputchain{
	my($setupex,$ruleex,$clearex,$tcex) = @_;
	if ($setupex == 1 && $ruleex ==1 && $clearex ==1){
		print("Test case ID $tcex-->Complete test case execution: SUCCESSFUL\n");
	}
	else{
		print("Test case ID $tcex-->Comelete test case execution: ERROR\n");
	}
	if($setupex ne 1){
		print("Rule configuration for test case ID $tcex: FAIL\n");
	}
	if($ruleex ne 1){
		print("Rule execution for test case ID $tcex: FAIL\n");
	}
	if($clearex ne 1){
		print("CLeardown phase for test case ID $tcex: FAIL\n");
	}
}


